package cn.aws360.boot.auth.starter.config;

import cn.aws360.boot.auth.api.pojo.properties.AuthProperties;
import cn.aws360.boot.base.api.constant.BaseConstant;
import cn.aws360.boot.base.api.pojo.response.ResultModel;
import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaHttpMethod;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author junnan
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
@ConditionalOnProperty(name = BaseConstant.APP + ".auth.enable", havingValue = "true")
public class AuthSaTokenAutoConfiguration implements WebMvcConfigurer {

    private final AuthProperties authProperties;

    private final String[] ignoreStaticPath = {
            "/favicon.ico", "/img/**", "/**/*.js", "/**/*.css", "/**/*.ttf", "/**/*.woff"
    };

    private final String[] ignoreSwaggerPath = {
            "/v2/**", "/webjars/**/**", "/swagger/**", "/swagger-resources/**", "/doc.html"
    };

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SaInterceptor()).addPathPatterns("/**");
    }

    @Bean
    public SaServletFilter getSaServletFilter() {
        return new SaServletFilter()
                .addInclude("/**")
                .addExclude(ArrayUtil.addAll(ignoreStaticPath, ignoreSwaggerPath, authProperties.getExcludes()))
                .setAuth(r -> SaRouter.match("/**", StpUtil::checkLogin))
                .setError(e -> {
                    if (e instanceof NotLoginException) {
                        SaHolder.getResponse().redirect("/login");
                    }
                    return JSON.toJSONString(ResultModel.fail(e.getMessage()));
                })
                .setBeforeAuth(r -> SaRouter.match(SaHttpMethod.OPTIONS).back());
    }

}
